<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>病历质控系统</title>
    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/css/bootstrap-icons.css" rel="stylesheet">
    <!-- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> -->
    <!-- <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css" rel="stylesheet"> -->
    <style>
        :root {
            --sidebar-width: 250px;
            --header-height: 60px;
        }
        
        body {
            font-size: 0.875rem;
            background-color: #f8f9fa;
        }
        
        .sidebar {
            position: fixed;
            top: 0;
            bottom: 0;
            left: 0;
            z-index: 100;
            padding: var(--header-height) 0 0;
            box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
            width: var(--sidebar-width);
            background-color: #fff;
        }
        
        .main-content {
            margin-left: var(--sidebar-width);
            padding-top: var(--header-height);
            min-height: calc(100vh - var(--header-height));
        }
        
        .navbar-brand {
            padding-top: .75rem;
            padding-bottom: .75rem;
            font-size: 1rem;
            background-color: rgba(0, 0, 0, .25);
        }
        
        .navbar {
            height: var(--header-height);
        }
        
        .file-item {
            transition: all 0.2s ease;
        }
        
        .file-item:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0,0,0,.1);
        }
        
        .card-header {
            font-weight: 600;
        }
        
        .upload-area {
            border: 2px dashed #dee2e6;
            border-radius: 0.375rem;
            padding: 2rem;
            text-align: center;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .upload-area:hover {
            border-color: #0d6efd;
            background-color: rgba(13, 110, 253, 0.05);
        }
        
        .file-icon {
            font-size: 2rem;
            color: #6c757d;
        }
        
        .action-btn {
            opacity: 0.7;
            transition: opacity 0.2s;
        }
        
        .file-item:hover .action-btn {
            opacity: 1;
        }
        
        .status-badge {
            font-size: 0.75em;
        }

        /* 保证 toast 内部可点击关闭按钮 */
        #floating-toast-container .toast { pointer-events: auto; min-width: 280px; }
    </style>
</head>
<body>
    <!-- 顶部导航栏 -->
    <nav class="navbar navbar-dark bg-dark fixed-top flex-md-nowrap shadow">
        <a class="navbar-brand col-md-3 col-lg-2 me-0 px-3" href="#">
            <i class="bi bi-clipboard-data me-2"></i>病历质控系统
        </a>
        <div class="navbar-nav ms-auto">
            <div class="nav-item text-nowrap px-3 text-white">
                <i class="bi bi-person-circle me-1"></i>管理员
            </div>
        </div>
    </nav>

    <div class="container-fluid">
        <div class="row">
            <!-- 侧边栏 -->
            <nav class="col-md-3 col-lg-2 d-md-block sidebar collapse">
                <div class="position-sticky pt-3">
                    <ul class="nav flex-column">
                        <li class="nav-item">
                            <a class="nav-link" href="#" id="nav-files">
                                <i class="bi bi-folder-fill me-2"></i>
                                文件管理
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#" id="nav-upload">
                                <i class="bi bi-cloud-arrow-up-fill me-2"></i>
                                上传文件
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#" id="nav-viewer">
                                <i class="bi bi-file-earmark-text-fill me-2"></i>
                                病历查看
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#" id="nav-govern">
                                <i class="bi bi-file-earmark-check-fill me-2"></i>
                                病历治理
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#" id="nav-report">
                                <i class="bi bi-file-earmark-bar-graph-fill me-2"></i>
                                治理报告
                            </a>
                        </li>
                    </ul>
                </div>
            </nav>

            <!-- 主内容区 -->
            <main class="col-md-9 ms-sm-auto col-lg-10 main-content">
                <div class="container-fluid px-4 py-4">
                    <!-- 文件管理视图 -->
                    <div id="files-view" class="view">
                        <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
                            <h1 class="h2">文件管理</h1>
                            <div class="btn-toolbar mb-2 mb-md-0">
                                <button type="button" class="btn btn-sm btn-outline-secondary" id="refresh-files">
                                    <i class="bi bi-arrow-repeat me-1"></i>刷新
                                </button>
                            </div>
                        </div>

                        <div class="row">
                            <!-- 输入文件区域 -->
                            <div class="col-md-6">
                                <div class="card">
                                    <div class="card-header d-flex justify-content-between align-items-center">
                                        <span><i class="bi bi-database-fill me-2"></i>输入文件</span>
                                        <div>
                                            <span class="badge bg-primary" id="data-count">0</span>
                                            <button class="btn btn-sm btn-outline-danger ms-2" id="delete-all-data" title="一键删除所有输入文件">
                                                <i class="bi bi-trash"></i> 一键删除
                                            </button>
                                        </div>
                                    </div>
                                    <div class="card-body">
                                        <div class="list-group" id="data-files-list">
                                            <!-- 数据文件将通过JS动态加载 -->
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <!-- 输出文件区域 -->
                            <div class="col-md-6">
                                <div class="card">
                                    <div class="card-header d-flex justify-content-between align-items-center">
                                        <span><i class="bi bi-file-earmark-bar-graph-fill me-2"></i>输出文件</span>
                                        <div>
                                            <span class="badge bg-success" id="output-count">0</span>
                                            <button class="btn btn-sm btn-outline-danger ms-2" id="delete-all-output" title="一键删除所有输出文件">
                                                <i class="bi bi-trash"></i> 一键删除
                                            </button>
                                        </div>
                                    </div>
                                    <div class="card-body">
                                        <div class="list-group" id="output-files-list">
                                            <!-- 输出文件将通过JS动态加载 -->
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- 上传文件视图 -->
                    <div id="upload-view" class="view d-none">
                        <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
                            <h1 class="h2">上传文件</h1>
                        </div>

                        <div class="row justify-content-center">
                            <div class="col-md-8">
                                <div class="card">
                                    <div class="card-header">
                                        <i class="bi bi-cloud-arrow-up-fill me-2"></i>上传病历文件
                                    </div>
                                    <div class="card-body">
                                        <div class="upload-area" id="drop-area">
                                            <i class="bi bi-file-earmark-arrow-up file-icon mb-3"></i>
                                            <h5>拖拽文件到此处或点击上传</h5>
                                            <p class="text-muted">支持JSON格式的病历文件</p>
                                            <button class="btn btn-primary mt-2" id="browse-btn">浏览文件</button>
                                            <input type="file" id="file-input" accept=".json" class="d-none">
                                            <button class="btn btn-outline-primary mt-2 ms-2" id="browse-dir-btn">上传目录</button>
                                            <input type="file" id="dir-input" webkitdirectory directory multiple class="d-none">
                                        </div>
                                        <div class="mt-3" id="upload-status"></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- 病历查看视图 -->
                    <div id="viewer-view" class="view d-none">
                        <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
                            <h1 class="h2">病历查看</h1>
                        </div>

                        <div class="row mb-3">
                            <div class="col-12">
                                <div class="card">
                                    <div class="card-body">
                                        <div class="d-flex align-items-center">
                                            <div class="me-3">
                                                <label class="form-label mb-0">输入文件</label>
                                            </div>
                                            <div class="flex-grow-1 me-3">
                                                <select class="form-select" id="data-file-select">
                                                    <option value="">请选择文件</option>
                                                </select>
                                            </div>
                                            <div>
                                                <button class="btn btn-primary" id="load-file-btn">
                                                    <i class="bi bi-eye-fill me-1"></i>查看病历
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="row">
                            <div class="col-md-12">
                                <div class="card">
                                    <div class="card-header d-flex justify-content-between align-items-center">
                                        <span><i class="bi bi-file-earmark-text-fill me-2"></i>病历内容</span>
                                        <span class="badge bg-info" id="current-file-name"></span>
                                    </div>
                                    <div class="card-body">
                                        <div id="medical-record-content" style="min-height: 400px; max-height: 600px; overflow-y: auto;">
                                            <div class="text-center text-muted py-5">
                                                <i class="bi bi-file-earmark-text fs-1"></i>
                                                <p class="mt-2">请选择上方文件查看病历内容</p>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- 治疗报告视图 -->
                    <div id="report-view" class="view d-none">
                        <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
                            <h1 class="h2">治理报告</h1>
                        </div>

                        <div class="row mb-3">
                            <div class="col-12">
                                <div class="card">
                                    <div class="card-body">
                                        <div class="d-flex align-items-center">
                                            <div class="me-3">
                                                <label class="form-label mb-0">输出文件</label>
                                            </div>
                                            <div class="flex-grow-1 me-3">
                                                <select class="form-select" id="output-file-select">
                                                    <option value="">请选择文件</option>
                                                </select>
                                            </div>
                                            <div>
                                                <button class="btn btn-primary" id="load-report-btn">
                                                    <i class="bi bi-eye-fill me-1"></i>查看报告
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="row">
                            <!-- 对应的病人信息 -->
                            <div class="col-md-4">
                                <div class="card h-100">
                                    <div class="card-header d-flex justify-content-between align-items-center">
                                        <span><i class="bi bi-person-fill me-2"></i>病人信息</span>
                                    </div>
                                    <div class="card-body d-flex flex-column">
                                        <div id="patient-info-content" class="flex-grow-1" style="min-height: 400px; max-height: 600px; overflow-y: auto;">
                                            <div class="text-center text-muted py-5">
                                                <i class="bi bi-person fs-1"></i>
                                                <p class="mt-2">请选择报告查看对应的病人信息</p>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <!-- 报告内容 -->
                            <div class="col-md-8">
                                <div class="card h-100">
                                    <div class="card-header d-flex justify-content-between align-items-center">
                                        <span><i class="bi bi-file-earmark-bar-graph-fill me-2"></i>报告内容</span>
                                        <span class="badge bg-info" id="current-report-name"></span>
                                    </div>
                                    <div class="card-body d-flex flex-column">
                                        <div id="report-content" class="flex-grow-1" style="min-height: 400px; max-height: 600px; overflow-y: auto;">
                                            <div class="text-center text-muted py-5">
                                                <i class="bi bi-file-earmark-bar-graph fs-1"></i>
                                                <p class="mt-2">请选择上方文件查看治理报告</p>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- 病历治理视图 -->
                    <div id="govern-view" class="view d-none">
                        <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
                            <h1 class="h2">病历治理</h1>
                        </div>

                        <div class="row mb-3">
                            <div class="col-12">
                                <div class="card">
                                    <div class="card-body">
                                        <div class="d-flex align-items-center">
                                            <div class="me-3">
                                                <label class="form-label mb-0">选择要治理的病历文件</label>
                                            </div>
                                            <div class="flex-grow-1 me-3">
                                            <div class="form-check form-check-inline" style="position: relative; top: 3px;">
                                                <input class="form-check-input" type="checkbox" id="select-all-data-files">
                                                <label class="form-check-label" for="select-all-data-files">全选</label>
                                            </div>
                                            </div>

                                            <div class="me-3">
                                                <label for="concurrency-setting" class="form-label me-2">并发数:</label>
                                                <input type="number" id="concurrency-setting" class="form-control d-inline-block" style="width: 80px;" min="1" max="10" value="3">
                                            </div>

                                            <div>
                                                <button class="btn btn-success" id="run-govern-btn">
                                                    <i class="bi bi-play-fill me-1"></i>开始治理
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="row">
                            <div class="col-md-12">
                                <div class="card">
                                    <div class="card-header d-flex justify-content-between align-items-center">
                                        <span><i class="bi bi-database-fill me-2"></i>待治理文件列表</span>
                                        <span class="badge bg-primary" id="selected-count">已选: 0</span>
                                    </div>
                                    <div class="card-body">
                                        <div id="data-files-govern-list" style="min-height: 300px; max-height: 500px; overflow-y: auto;">
                                            <div class="text-center text-muted py-5">
                                                <i class="bi bi-folder fs-1"></i>
                                                <p class="mt-2">加载中...</p>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="row mt-3">
                            <div class="col-md-12">
                                <div class="card">
                                    <div class="card-header">
                                        <span><i class="bi bi-terminal-fill me-2"></i>治理日志</span>
                                    </div>
                                    <div class="card-body">
                                        <div id="govern-log" style="min-height: 200px; max-height: 300px; overflow-y: auto; background-color: #f8f9fa; font-family: monospace; font-size: 0.9em;">
                                            <div class="text-muted">等待开始治理...</div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </main>
        </div>
    </div>

    <!-- 文件操作模态框 -->
    <div class="modal fade" id="fileModal" tabindex="-1">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="fileModalLabel">文件详情</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <pre id="file-content" style="max-height: 500px; overflow-y: auto;"></pre>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
                </div>
            </div>
        </div>
    </div>

    <!-- 删除确认模态框 -->
    <div class="modal fade" id="deleteConfirmModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">确认删除</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <p>确定要删除文件 "<span id="delete-filename"></span>" 吗？此操作不可撤销。</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                    <button type="button" class="btn btn-danger" id="confirm-delete-btn">删除</button>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 删除成功模态框（保留也不会再用于提示） -->
    <div class="modal fade" id="deleteSuccessModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">删除成功</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <p>文件 "<span id="deleted-filename"></span>" 已成功删除。</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary" data-bs-dismiss="modal">确定</button>
                </div>
            </div>
        </div>
    </div>

    <!-- 浮动通知容器（页面内弹窗，不占用顶栏） -->
    <div id="floating-toast-container" class="position-fixed top-50 start-50 translate-middle" style="z-index:1080; pointer-events: none; width: auto; max-width: 90%;"></div>
    
    <!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> -->
     <script src="../static/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
     <script src="../static/js/chart.js" crossorigin="anonymous"></script>
    <script>
        // 当前视图管理
        let currentView = 'files';
        
        // 添加全局变量来存储选中的文件
        let selectedGovernFiles = new Set();
        let isSelectAllChecked = false;
        
        // DOM元素引用
        const views = {
            files: document.getElementById('files-view'),
            upload: document.getElementById('upload-view'),
            viewer: document.getElementById('viewer-view'),
            report: document.getElementById('report-view'),
            govern: document.getElementById('govern-view')
        };
        
        // 导航链接
        const navLinks = {
            files: document.getElementById('nav-files'),
            upload: document.getElementById('nav-upload'),
            viewer: document.getElementById('nav-viewer'),
            report: document.getElementById('nav-report'),
            govern: document.getElementById('nav-govern')
        };
        
        // 切换视图函数
        function switchView(viewName) {
            // 隐藏所有视图
            Object.values(views).forEach(view => view.classList.add('d-none'));
            
            // 显示目标视图
            views[viewName].classList.remove('d-none');
            
            // 更新导航状态
            Object.values(navLinks).forEach(link => link.classList.remove('active'));
            navLinks[viewName].classList.add('active');
            
            currentView = viewName;
            
            // 根据视图执行相应操作
            if (viewName === 'files') {
                loadFiles();
            } else if (viewName === 'viewer') {
                loadViewerFiles();
            } else if (viewName === 'report') {
                loadReportFiles();
            } else if (viewName === 'govern') {
                loadGovernFiles();
            }
        }
        
        // 事件监听器
        document.addEventListener('DOMContentLoaded', function() {
            // 导航点击事件
            navLinks.files.addEventListener('click', (e) => {
                e.preventDefault();
                switchView('files');
            });
            
            navLinks.upload.addEventListener('click', (e) => {
                e.preventDefault();
                switchView('upload');
            });
            
            navLinks.viewer.addEventListener('click', (e) => {
                e.preventDefault();
                switchView('viewer');
            });
            
            navLinks.govern.addEventListener('click', (e) => {
                e.preventDefault();
                switchView('govern');
            });
            
            navLinks.report.addEventListener('click', (e) => {
                e.preventDefault();
                switchView('report');
            });
            
            // 刷新按钮
            document.getElementById('refresh-files').addEventListener('click', loadFiles);
            
            // 添加一键删除事件监听器
            document.getElementById('delete-all-data').addEventListener('click', () => {
                deleteAllFiles('data');
            });
            
            document.getElementById('delete-all-output').addEventListener('click', () => {
                deleteAllFiles('output');
            });
            
            // 文件上传相关事件
            setupUploadEvents();
            
            // 病历查看相关事件
            setupViewerEvents();
            
            // 治理报告相关事件
            setupReportEvents();
            
            // 病历治理相关事件
            setupGovernEvents();
            
            // 初始化加载文件列表
            loadFiles();
        });
        
        // 加载病历治理的文件列表
        function loadGovernFiles() {
            fetch('/api/files')
                .then(response => response.json())
                .then(data => {
                    renderGovernFileList(data.data_files);
                })
                .catch(error => {
                    console.error('Error loading files for govern:', error);
                    alert('加载文件列表失败');
                });
        }
        
        // 渲染病历治理文件列表
        function renderGovernFileList(files) {
            const container = document.getElementById('data-files-govern-list');
            container.innerHTML = '';
            
            if (files.length === 0) {
                container.innerHTML = `
                    <div class="text-center py-5 text-muted">
                        <i class="bi bi-folder me-2"></i>暂无文件
                    </div>
                `;
                return;
            }
            
            files.forEach(file => {
                const fileItem = document.createElement('div');
                fileItem.className = 'list-group-item';
                fileItem.innerHTML = `
                    <div class="d-flex align-items-center">
                        <div class="form-check me-3">
                            <input class="form-check-input govern-file-checkbox" type="checkbox" value="${file.name}" id="govern-${file.name}">
                            <label class="form-check-label" for="govern-${file.name}"></label>
                        </div>
                        <div class="flex-grow-1">
                            <h6 class="mb-1">
                                <i class="bi bi-file-text me-2"></i>${file.name}
                            </h6>
                            <small class="text-muted">
                                <i class="bi bi-info-circle me-1"></i>大小: ${formatFileSize(file.size)}
                                <i class="bi bi-clock me-1 ms-2"></i>修改时间: ${new Date(file.modified * 1000).toLocaleString()}
                            </small>
                        </div>
                    </div>
                `;
                container.appendChild(fileItem);
            });
            
            // 恢复之前选中的文件状态
            document.querySelectorAll('.govern-file-checkbox').forEach(checkbox => {
                if (selectedGovernFiles.has(checkbox.value)) {
                    checkbox.checked = true;
                }
                checkbox.addEventListener('change', updateSelectedCount);
            });
            
            // 恢复全选状态
            const selectAllCheckbox = document.getElementById('select-all-data-files');
            selectAllCheckbox.checked = isSelectAllChecked;
            if (isSelectAllChecked) {
                document.querySelectorAll('.govern-file-checkbox').forEach(checkbox => {
                    checkbox.checked = true;
                    selectedGovernFiles.add(checkbox.value);
                });
            }
            
            // 绑定全选功能
            selectAllCheckbox.addEventListener('change', function() {
                const checkboxes = document.querySelectorAll('.govern-file-checkbox');
                checkboxes.forEach(checkbox => {
                    checkbox.checked = this.checked;
                    if (this.checked) {
                        selectedGovernFiles.add(checkbox.value);
                    } else {
                        selectedGovernFiles.delete(checkbox.value);
                    }
                });
                isSelectAllChecked = this.checked;
                updateSelectedCount();
            });
            
            updateSelectedCount();
        }
        
        // 更新已选文件计数
        function updateSelectedCount() {
            const selectedCheckboxes = document.querySelectorAll('.govern-file-checkbox:checked');
            const count = selectedCheckboxes.length;
            document.getElementById('selected-count').textContent = `已选: ${count}`;
            
            // 更新selectedGovernFiles集合
            selectedGovernFiles.clear();
            selectedCheckboxes.forEach(checkbox => {
                selectedGovernFiles.add(checkbox.value);
            });
            
            // 检查是否全部选中以更新全选框状态
            const totalCheckboxes = document.querySelectorAll('.govern-file-checkbox').length;
            const selectAllCheckbox = document.getElementById('select-all-data-files');
            if (totalCheckboxes > 0 && count === totalCheckboxes) {
                isSelectAllChecked = true;
                selectAllCheckbox.checked = true;
            } else if (count === 0) {
                isSelectAllChecked = false;
                selectAllCheckbox.checked = false;
            }
        }
        
        // 设置病历治理事件
        function setupGovernEvents() {
            document.getElementById('run-govern-btn').addEventListener('click', runGovernProcess);
        }
        
        // 执行病历治理流程
        function runGovernProcess() {
            const selectedFiles = Array.from(document.querySelectorAll('.govern-file-checkbox:checked'))
                .map(checkbox => checkbox.value);
            
            if (selectedFiles.length === 0) {
                alert('请至少选择一个文件进行治理');
                return;
            }
            
            // 获取并发数设置
            const concurrency = parseInt(document.getElementById('concurrency-setting').value) || 3;
            
            // 禁用按钮并更新界面
            const runBtn = document.getElementById('run-govern-btn');
            runBtn.disabled = true;
            runBtn.innerHTML = '<i class="bi bi-hourglass-split me-1"></i>治理中...';
            
            // 清空日志区域
            const logContainer = document.getElementById('govern-log');
            logContainer.innerHTML = '';
            
            // 添加开始日志
            addLogMessage(`开始治理 ${selectedFiles.length} 个文件 (并发数: ${concurrency})...`, 'info');
            
            // 使用后端批量处理接口
            fetch('/api/run-quality-control-batch', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    filenames: selectedFiles,
                    concurrency: concurrency
                })
            })
            .then(response => {
                if (response.ok) {
                    return response.json();
                } else {
                    throw new Error(`处理失败: ${response.status}`);
                }
            })
            .then(data => {
                // 处理结果
                let successCount = 0;
                let failCount = 0;
                
                data.results.forEach(result => {
                    if (result.error) {
                        addLogMessage(`✗ 文件 ${result.filename} 处理失败: ${result.error}`, 'error');
                        writeLogToFile(`文件 ${result.filename} 治理失败: ${result.error}`);
                        failCount++;
                    } else {
                        addLogMessage(`✓ 文件 ${result.filename} 处理完成，得分: ${result.result['总体评分']}`, 'success');
                        writeLogToFile(`文件 ${result.filename} 治理完成，得分: ${result.result['总体评分']}`);
                        successCount++;
                    }
                });
                
                addLogMessage(`治理完成！共处理 ${selectedFiles.length} 个文件，成功: ${successCount}，失败: ${failCount}。`, 'info');
            })
            .catch(error => {
                addLogMessage(`✗ 处理过程中出现错误: ${error.message}`, 'error');
                writeLogToFile(`治理过程中出现错误: ${error.message}`);
            })
            .finally(() => {
                runBtn.disabled = false;
                runBtn.innerHTML = '<i class="bi bi-play-fill me-1"></i>开始治理';
                loadFiles(); // 刷新文件列表
            });
        }
        
        // 添加日志消息
        function addLogMessage(message, type) {
            const logContainer = document.getElementById('govern-log');
            const logEntry = document.createElement('div');
            
            const timestamp = new Date().toLocaleTimeString();
            const typeClass = {
                'info': 'text-primary',
                'success': 'text-success',
                'error': 'text-danger'
            }[type] || 'text-muted';
            
            logEntry.className = `log-entry ${typeClass} mb-1`;
            logEntry.innerHTML = `[${timestamp}] ${message}`;
            
            logContainer.appendChild(logEntry);
            logContainer.scrollTop = logContainer.scrollHeight; // 自动滚动到底部
        }
        
        // 写入日志到文件
        function writeLogToFile(message) {
            const timestamp = new Date().toISOString();
            const logMessage = `[${timestamp}] ${message}\n`;
            
            // 发送日志到后端写入文件
            fetch('/api/write-log', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ message: logMessage })
            }).catch(error => {
                console.error('写入日志文件失败:', error);
            });
        }
        
        // 加载文件列表
        function loadFiles() {
            fetch('/api/files')
                .then(response => response.json())
                .then(data => {
                    renderFileList('data', data.data_files);
                    renderFileList('output', data.output_files);
                    
                    // 更新计数
                    document.getElementById('data-count').textContent = data.data_files.length;
                    document.getElementById('output-count').textContent = data.output_files.length;
                })
                .catch(error => {
                    console.error('Error loading files:', error);
                    alert('加载文件列表失败');
                });
        }
        
        // 加载病历查看器的文件列表
        function loadViewerFiles() {
            fetch('/api/files')
                .then(response => response.json())
                .then(data => {
                    const select = document.getElementById('data-file-select');
                    select.innerHTML = '<option value="">请选择文件</option>';
                    
                    data.data_files.forEach(file => {
                        const option = document.createElement('option');
                        option.value = file.name;
                        option.textContent = file.name;
                        select.appendChild(option);
                    });
                })
                .catch(error => {
                    console.error('Error loading files for viewer:', error);
                    alert('加载文件列表失败');
                });
        }
        
        // 加载治理报告的文件列表
        function loadReportFiles() {
            fetch('/api/files')
                .then(response => response.json())
                .then(data => {
                    const select = document.getElementById('output-file-select');
                    select.innerHTML = '<option value="">请选择文件</option>';
                    
                    data.output_files.forEach(file => {
                        const option = document.createElement('option');
                        option.value = file.name;
                        option.textContent = file.name;
                        select.appendChild(option);
                    });
                })
                .catch(error => {
                    console.error('Error loading files for report:', error);
                    alert('加载文件列表失败');
                });
        }
        
        // 设置病历查看器事件
        function setupViewerEvents() {
            document.getElementById('load-file-btn').addEventListener('click', function() {
                const filename = document.getElementById('data-file-select').value;
                if (!filename) {
                    alert('请选择一个文件');
                    return;
                }
                viewMedicalRecord(filename);
            });
        }
        
        // 设置治理报告事件
        function setupReportEvents() {
            document.getElementById('load-report-btn').addEventListener('click', function() {
                const filename = document.getElementById('output-file-select').value;
                if (!filename) {
                    alert('请选择一个文件');
                    return;
                }
                viewReport(filename);
            });
        }
        
        // 查看病历内容
        function viewMedicalRecord(filename) {
            fetch(`/api/content/data/${filename}`)
                .then(response => {
                    if (!response.ok) throw new Error('文件加载失败');
                    return response.json();
                })
                .then(data => {
                    document.getElementById('current-file-name').textContent = filename;
                    renderMedicalRecord(data);
                })
                .catch(error => {
                    console.error('Error viewing medical record:', error);
                    alert('查看病历内容失败');
                });
        }
        
        // 查看治理报告内容
        function viewReport(filename) {
            fetch(`/api/content/output/${filename}`)
                .then(response => {
                    if (!response.ok) throw new Error('文件加载失败');
                    return response.json();
                })
                .then(data => {
                    document.getElementById('current-report-name').textContent = filename;
                    renderReport(data);
                    
                    // 提取对应的病人信息
                    // 根据需求，报告文件名是病历文件名加上"_result"后缀
                    const patientId = filename.replace('_result.json', '.json');
                    return fetch(`/api/content/data/${patientId}`)
                        .then(response => {
                            if (response.ok) {
                                return response.json();
                            } else {
                                throw new Error('病人信息文件不存在');
                            }
                        })
                        .then(patientData => {
                            renderPatientInfo(patientData);
                        })
                        .catch(error => {
                            console.error('Error loading patient info:', error);
                            renderPatientInfo(null);
                        });
                })
                .catch(error => {
                    console.error('Error viewing report:', error);
                    alert('查看报告内容失败');
                });
        }
        
        // 渲染病人信息
        function renderPatientInfo(data) {
            const container = document.getElementById('patient-info-content');
            
            if (!data) {
                container.innerHTML = `
                    <div class="text-center text-muted py-5">
                        <i class="bi bi-person-x fs-1"></i>
                        <p class="mt-2">未找到对应的病人信息</p>
                    </div>
                `;
                return;
            }
            
            // 清空容器
            container.innerHTML = '';
            
            // 创建病人信息展示
            const infoCard = document.createElement('div');
            infoCard.className = 'card';
            
            const cardBody = document.createElement('div');
            cardBody.className = 'card-body';
            
            // 标题
            const title = document.createElement('h5');
            title.className = 'card-title mb-3';
            title.innerHTML = '<i class="bi bi-person-badge me-2"></i>基本信息';
            cardBody.appendChild(title);
            
            // 病人信息表格
            const table = document.createElement('table');
            table.className = 'table table-borderless table-sm';
            
            const tbody = document.createElement('tbody');
            
            // 患者信息字段
            const patientInfo = data['患者信息'] || {};
            const fields = [
                { key: '姓名', value: patientInfo['姓名'] },
                { key: '性别', value: patientInfo['性别'] },
                { key: '年龄', value: patientInfo['年龄'] },
                { key: '身份证号', value: patientInfo['身份证号'] },
                { key: '联系方式', value: patientInfo['联系方式'] },
                { key: '住址', value: patientInfo['住址'] },
                // 添加更多字段
                { key: '职业', value: patientInfo['职业'] },
                { key: '婚姻状况', value: patientInfo['婚姻状况'] },
                { key: '民族', value: patientInfo['民族'] },
                { key: '出生日期', value: patientInfo['出生日期'] },
                { key: '紧急联系人', value: patientInfo['紧急联系人'] },
                { key: '紧急联系电话', value: patientInfo['紧急联系电话'] },
                { key: '血型', value: patientInfo['血型'] },
                { key: '过敏史', value: patientInfo['过敏史'] },
                { key: '医保类型', value: patientInfo['医保类型'] }
            ];
            
            fields.forEach(field => {
                if (field.value) {
                    const row = document.createElement('tr');
                    
                    const keyCell = document.createElement('td');
                    keyCell.innerHTML = `<strong>${field.key}</strong>`;
                    
                    const valueCell = document.createElement('td');
                    valueCell.textContent = field.value;
                    
                    row.appendChild(keyCell);
                    row.appendChild(valueCell);
                    tbody.appendChild(row);
                }
            });
            
            table.appendChild(tbody);
            cardBody.appendChild(table);
            
            // 病情信息
            const conditionInfo = data['病情信息'] || {};
            if (conditionInfo['主诉'] || conditionInfo['现病史'] || conditionInfo['既往史']) {
                const conditionTitle = document.createElement('h6');
                conditionTitle.className = 'mt-3 mb-2';
                conditionTitle.innerHTML = '<i class="bi bi-clipboard2-pulse me-2"></i>病情信息';
                cardBody.appendChild(conditionTitle);
                
                const conditionTable = document.createElement('table');
                conditionTable.className = 'table table-borderless table-sm';
                
                const conditionTbody = document.createElement('tbody');
                
                const conditionFields = [
                    { key: '主诉', value: conditionInfo['主诉'] },
                    { key: '现病史', value: conditionInfo['现病史'] },
                    { key: '既往史', value: conditionInfo['既往史'] },
                    // 添加更多病情相关信息
                    { key: '体格检查', value: conditionInfo['体格检查'] },
                    { key: '诊断', value: conditionInfo['诊断'] },
                    { key: '治疗方案', value: conditionInfo['治疗方案'] }
                ];
                
                conditionFields.forEach(field => {
                    if (field.value) {
                        const row = document.createElement('tr');
                        
                        const keyCell = document.createElement('td');
                        keyCell.innerHTML = `<strong>${field.key}</strong>`;
                        keyCell.style.width = '20%';
                        
                        const valueCell = document.createElement('td');
                        valueCell.textContent = field.value;
                        valueCell.style.wordBreak = 'break-word';
                        
                        row.appendChild(keyCell);
                        row.appendChild(valueCell);
                        conditionTbody.appendChild(row);
                    }
                });
                
                conditionTable.appendChild(conditionTbody);
                cardBody.appendChild(conditionTable);
            }
            
            infoCard.appendChild(cardBody);
            container.appendChild(infoCard);
        }
        
        // 渲染病历内容
        function renderMedicalRecord(data) {
            const container = document.getElementById('medical-record-content');
            
            // 清空容器
            container.innerHTML = '';
            
            // 创建折叠面板容器
            const accordion = document.createElement('div');
            accordion.className = 'accordion';
            accordion.id = 'medicalRecordAccordion';
            
            // 按照病历结构渲染
            const sections = [
                { key: '患者信息', title: '患者信息', data: data['患者信息'] },
                { key: '病情信息', title: '病情信息', data: data['病情信息'] },
                { key: '用药信息', title: '用药信息', data: data['用药信息'] },
                { key: '嘱托与注意事项', title: '嘱托与注意事项', data: data['嘱托与注意事项'] },
                { key: '医生信息', title: '医生信息', data: data['医生信息'] }
            ];
            
            sections.forEach((section, index) => {
                if (!section.data) return;
                
                const card = document.createElement('div');
                card.className = 'accordion-item';
                
                const headerId = `heading${index}`;
                const collapseId = `collapse${index}`;
                
                card.innerHTML = `
                    <h2 class="accordion-header" id="${headerId}">
                        <button class="accordion-button ${index === 0 ? '' : 'collapsed'}" type="button" data-bs-toggle="collapse" data-bs-target="#${collapseId}" aria-expanded="${index === 0 ? 'true' : 'false'}" aria-controls="${collapseId}">
                            ${section.title}
                        </button>
                    </h2>
                    <div id="${collapseId}" class="accordion-collapse collapse ${index === 0 ? 'show' : ''}" aria-labelledby="${headerId}">
                        <div class="accordion-body">
                            <div id="content-${section.key}"></div>
                        </div>
                    </div>
                `;
                
                // 渲染具体内容
                const contentContainer = card.querySelector(`#content-${section.key}`);
                renderObject(contentContainer, section.data);
                
                accordion.appendChild(card);
            });
            
            container.appendChild(accordion);
        }
        
        // 渲染治理报告内容
        function renderReport(data) {
            const container = document.getElementById('report-content');
            
            // 清空容器
            container.innerHTML = '';
            
            // 创建图表容器
            const chartRow = document.createElement('div');
            chartRow.className = 'row mb-4';
            chartRow.innerHTML = `
                <div class="col-md-6">
                    <div class="card">
                        <div class="card-header">
                            <span class="fw-bold">评分概览</span>
                        </div>
                        <div class="card-body">
                            <canvas id="scoreChart" height="300"></canvas>
                        </div>
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="card">
                        <div class="card-header">
                            <span class="fw-bold">扣分详情</span>
                        </div>
                        <div class="card-body">
                            <canvas id="detailChart" height="300"></canvas>
                        </div>
                    </div>
                </div>
            `;
            container.appendChild(chartRow);
            
            // 创建折叠面板容器
            const accordion = document.createElement('div');
            accordion.className = 'accordion';
            accordion.id = 'reportAccordion';
            
            // 按照报告结构渲染
            const sections = [
                { key: 'summary', title: '报告摘要', data: {
                    '总体评分': data['总体评分'],
                    '评分细则': data['评分细则']
                }},
                { key: 'issues', title: '主要问题', data: data['主要问题'] },
                { key: 'suggestions', title: '改进建议', data: data['改进建议'] },
                { key: 'details', title: '详细检查结果', data: data['各阶段检查结果'] }
            ];
            
            sections.forEach((section, index) => {
                if (!section.data) return;
                
                const card = document.createElement('div');
                card.className = 'accordion-item';
                
                const headerId = `reportHeading${index}`;
                const collapseId = `reportCollapse${index}`;
                
                card.innerHTML = `
                    <h2 class="accordion-header" id="${headerId}">
                        <button class="accordion-button ${index === 0 ? '' : 'collapsed'}" type="button" data-bs-toggle="collapse" data-bs-target="#${collapseId}" aria-expanded="${index === 0 ? 'true' : 'false'}" aria-controls="${collapseId}">
                            ${section.title}
                        </button>
                    </h2>
                    <div id="${collapseId}" class="accordion-collapse collapse ${index === 0 ? 'show' : ''}" aria-labelledby="${headerId}">
                        <div class="accordion-body">
                            <div id="content-${section.key}"></div>
                        </div>
                    </div>
                `;
                
                // 渲染具体内容
                const contentContainer = card.querySelector(`#content-${section.key}`);
                renderObject(contentContainer, section.data);
                
                accordion.appendChild(card);
            });
            
            container.appendChild(accordion);
            
            // 绘制图表
            renderCharts(data);
        }
        
        // 绘制图表
        function renderCharts(data) {
            // 总评分饼图
            const scoreCtx = document.getElementById('scoreChart').getContext('2d');
            const scoreChart = new Chart(scoreCtx, {
                type: 'pie',
                data: {
                    labels: ['得分', '失分'],
                    datasets: [{
                        data: [data['总体评分'], 100 - data['总体评分']],
                        backgroundColor: [
                            '#28a745',  // 得分 - 绿色
                            '#dc3545'   // 失分 - 红色
                        ],
                        borderWidth: 1
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            position: 'bottom'
                        },
                        tooltip: {
                            callbacks: {
                                label: function(context) {
                                    return `${context.label}: ${context.raw}分`;
                                }
                            }
                        }
                    },
                    animation: {
                        animateRotate: true,
                        animateScale: true,
                        duration: 1000
                    }
                }
            });
            
            // 评分细则饼图
            const detailCtx = document.getElementById('detailChart').getContext('2d');
            const detailData = data['评分细则'];
            const detailChart = new Chart(detailCtx, {
                type: 'pie',
                data: {
                    labels: Object.keys(detailData),
                    datasets: [{
                        data: Object.values(detailData),
                        backgroundColor: [
                            '#ffc107',  // 字段规范性 - 黄色
                            '#17a2b8',  // 内容完整性 - 蓝色
                            '#6f42c1',  // 医学逻辑性 - 紫色
                            '#fd7e14'   // 内容一致性 - 橙色
                        ],
                        borderWidth: 1
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            position: 'bottom'
                        },
                        tooltip: {
                            callbacks: {
                                label: function(context) {
                                    return `${context.label}: ${context.raw}分`;
                                }
                            }
                        }
                    },
                    animation: {
                        animateRotate: true,
                        animateScale: true,
                        duration: 1000
                    }
                }
            });
        }
        
        // 渲染对象内容
        function renderObject(container, data) {
            if (Array.isArray(data)) {
                renderArray(container, data);
            } else if (typeof data === 'object' && data !== null) {
                const table = document.createElement('table');
                table.className = 'table table-striped';
                
                const tbody = document.createElement('tbody');
                
                Object.entries(data).forEach(([key, value]) => {
                    const row = document.createElement('tr');
                    
                    const keyCell = document.createElement('td');
                    keyCell.innerHTML = `<strong>${key}</strong>`;
                    
                    const valueCell = document.createElement('td');
                    if (Array.isArray(value)) {
                        if (value.length > 0 && typeof value[0] === 'object') {
                            // 对象数组特殊处理
                            const innerContainer = document.createElement('div');
                            renderArray(innerContainer, value);
                            valueCell.appendChild(innerContainer);
                        } else {
                            // 为数组项添加换行显示
                            const list = document.createElement('ul');
                            list.className = 'mb-0 ps-3';
                            value.forEach(item => {
                                const listItem = document.createElement('li');
                                listItem.textContent = item;
                                list.appendChild(listItem);
                            });
                            valueCell.appendChild(list);
                        }
                    } else if (typeof value === 'object' && value !== null) {
                        // 嵌套对象特殊处理
                        const innerContainer = document.createElement('div');
                        renderObject(innerContainer, value);
                        valueCell.appendChild(innerContainer);
                    } else {
                        valueCell.textContent = value;
                    }
                    
                    row.appendChild(keyCell);
                    row.appendChild(valueCell);
                    tbody.appendChild(row);
                });
                
                table.appendChild(tbody);
                container.appendChild(table);
            } else {
                container.textContent = data;
            }
        }
        
        // 渲染数组内容
        function renderArray(container, data) {
            if (data.length > 0 && typeof data[0] === 'object') {
                // 对象数组
                data.forEach((item, index) => {
                    const card = document.createElement('div');
                    card.className = 'card mb-2';
                    
                    const cardBody = document.createElement('div');
                    cardBody.className = 'card-body';
                    
                    const title = document.createElement('h6');
                    title.className = 'card-title';
                    title.textContent = `项目 ${index + 1}`;
                    cardBody.appendChild(title);
                    
                    const innerContainer = document.createElement('div');
                    renderObject(innerContainer, item);
                    cardBody.appendChild(innerContainer);
                    
                    card.appendChild(cardBody);
                    container.appendChild(card);
                });
            } else {
                // 简单数组
                const list = document.createElement('ul');
                list.className = 'list-group';
                
                data.forEach(item => {
                    const listItem = document.createElement('li');
                    listItem.className = 'list-group-item';
                    listItem.textContent = item;
                    list.appendChild(listItem);
                });
                
                container.appendChild(list);
            }
        }
        
        // 渲染文件列表
        function renderFileList(type, files) {
            const container = document.getElementById(`${type}-files-list`);
            container.innerHTML = '';
            
            if (files.length === 0) {
                container.innerHTML = `
                    <div class="text-center py-5 text-muted">
                        <i class="bi bi-folder me-2"></i>暂无文件
                    </div>
                `;
                return;
            }
            
            files.forEach(file => {
                const fileItem = document.createElement('div');
                fileItem.className = 'list-group-item list-group-item-action file-item';
                fileItem.innerHTML = `
                    <div class="d-flex w-100 justify-content-between align-items-center">
                        <div>
                            <h6 class="mb-1">
                                <i class="bi bi-file-text me-2"></i>${file.name}
                            </h6>
                            <small class="text-muted">
                                <i class="bi bi-info-circle me-1"></i>大小: ${formatFileSize(file.size)}
                            </small>
                        </div>
                        <div>
                            <button class="btn btn-sm btn-outline-primary action-btn me-1" onclick="viewFile('${type}', '${file.name}')">
                                <i class="bi bi-eye"></i>
                            </button>
                            <button class="btn btn-sm btn-outline-success action-btn me-1" onclick="downloadFile('${type}', '${file.name}')">
                                <i class="bi bi-download"></i>
                            </button>
                            <button class="btn btn-sm btn-outline-danger action-btn" onclick="deleteFile('${type}', '${file.name}')">
                                <i class="bi bi-trash"></i>
                            </button>
                        </div>
                    </div>
                    <small class="text-muted">
                        <i class="bi bi-clock me-1"></i>修改时间: ${new Date(file.modified * 1000).toLocaleString()}
                    </small>
                `;
                container.appendChild(fileItem);
            });
        }
        
        // 查看文件内容
        function viewFile(type, filename) {
            fetch(`/api/content/${type}/${filename}`)
                .then(response => {
                    if (!response.ok) throw new Error('文件加载失败');
                    return response.json();
                })
                .then(data => {
                    document.getElementById('fileModalLabel').textContent = `文件详情: ${filename}`;
                    document.getElementById('file-content').textContent = JSON.stringify(data, null, 2);
                    new bootstrap.Modal(document.getElementById('fileModal')).show();
                })
                .catch(error => {
                    console.error('Error viewing file:', error);
                    alert('查看文件内容失败');
                });
        }
        
        // 下载文件
        function downloadFile(type, filename) {
            window.location.href = `/api/download/${type}/${filename}`;
        }
        
        // 删除文件
        function deleteFile(type, filename) {
            // 设置要删除的文件信息
            document.getElementById('delete-filename').textContent = filename;
            document.getElementById('confirm-delete-btn').onclick = function() {
                performDelete(type, filename);
                bootstrap.Modal.getInstance(document.getElementById('deleteConfirmModal')).hide();
            };
            
            // 显示确认模态框
            new bootstrap.Modal(document.getElementById('deleteConfirmModal')).show();
        }
        
        // 执行实际删除操作
        function performDelete(type, filename) {
            fetch(`/api/delete/${type}/${filename}`, {
                method: 'DELETE'
            })
            .then(response => {
                if (response.ok) {
                    loadFiles();
                    // 修改: 使用删除成功模态框替代浮动toast
                    document.getElementById('deleted-filename').textContent = filename;
                    new bootstrap.Modal(document.getElementById('deleteSuccessModal')).show();
                } else {
                    throw new Error('删除失败');
                }
            })
            .catch(error => {
                console.error('Error deleting file:', error);
                // 修改: 使用删除成功模态框显示错误信息
                document.getElementById('deleted-filename').textContent = filename + ' (删除失败: ' + error.message + ')';
                new bootstrap.Modal(document.getElementById('deleteSuccessModal')).show();
            });
        }

        // 使用 Bootstrap Toast 在页面内显示浮动通知（不占用顶部栏）
        function showFloatingToast(message, type = 'info') {
            const container = document.getElementById('floating-toast-container');
            if (!container) return;

            const bgClass = {
                success: 'bg-success text-white',
                danger: 'bg-danger text-white',
                warning: 'bg-warning text-dark',
                info: 'bg-info text-dark'
            }[type] || 'bg-info text-dark';

            const closeBtnClass = (type === 'success' || type === 'danger') ? 'btn-close btn-close-white' : 'btn-close';

            const toastEl = document.createElement('div');
            toastEl.className = `toast align-items-center ${bgClass} border-0`;
            toastEl.setAttribute('role', 'alert');
            toastEl.setAttribute('aria-live', 'assertive');
            toastEl.setAttribute('aria-atomic', 'true');
            toastEl.innerHTML = `
                <div class="d-flex">
                    <div class="toast-body">${message}</div>
                    <button type="button" class="${closeBtnClass} me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
                </div>
            `;

            // 添加并显示
            container.appendChild(toastEl);
            const bsToast = new bootstrap.Toast(toastEl, { delay: 4000 });
            bsToast.show();

            // 隐藏后从 DOM 移除
            toastEl.addEventListener('hidden.bs.toast', () => {
                toastEl.remove();
            });
        }

        // 格式化文件大小
        function formatFileSize(bytes) {
            if (bytes === 0) return '0 Bytes';
            const k = 1024;
            const sizes = ['Bytes', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }
        
        // 设置上传事件
        function setupUploadEvents() {
            const dropArea = document.getElementById('drop-area');
            const fileInput = document.getElementById('file-input');
            const browseBtn = document.getElementById('browse-btn');
            const uploadStatus = document.getElementById('upload-status');
            // 新增目录上传相关
            const browseDirBtn = document.getElementById('browse-dir-btn');
            const dirInput = document.getElementById('dir-input');

            // 点击浏览按钮触发文件选择
            browseBtn.addEventListener('click', () => {
                fileInput.click();
            });

            // 新增：点击上传目录按钮触发目录选择
            browseDirBtn.addEventListener('click', () => {
                dirInput.click();
            });

            // 文件选择后触发上传（单文件）
            fileInput.addEventListener('change', (e) => {
                if (e.target.files.length > 0) {
                    uploadFile(e.target.files[0]);
                }
            });

            // 新增：目录选择后上传所有 JSON 文件
            dirInput.addEventListener('change', (e) => {
                const files = Array.from(e.target.files).filter(f => f.name.endsWith('.json'));
                if (files.length === 0) {
                    uploadStatus.innerHTML = '<div class="alert alert-danger">目录中没有 JSON 文件</div>';
                    return;
                }
                uploadMultipleFiles(files);
            });

            // 拖拽上传事件
            ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
                dropArea.addEventListener(eventName, preventDefaults, false);
            });

            function preventDefaults(e) {
                e.preventDefault();
                e.stopPropagation();
            }

            ['dragenter', 'dragover'].forEach(eventName => {
                dropArea.addEventListener(eventName, highlight, false);
            });

            ['dragleave', 'drop'].forEach(eventName => {
                dropArea.addEventListener(eventName, unhighlight, false);
            });

            function highlight() {
                dropArea.style.borderColor = '#0d6efd';
                dropArea.style.backgroundColor = 'rgba(13, 110, 253, 0.05)';
            }

            function unhighlight() {
                dropArea.style.borderColor = '#dee2e6';
                dropArea.style.backgroundColor = '';
            }

            dropArea.addEventListener('drop', handleDrop, false);

            // 修改拖拽处理，支持拖拽目录
            function handleDrop(e) {
                const dt = e.dataTransfer;
                const items = dt.items;
                let files = [];

                if (items && items.length > 0) {
                    // 支持拖拽目录
                    let pending = 0;
                    let allFiles = [];
                    for (let i = 0; i < items.length; i++) {
                        const item = items[i].webkitGetAsEntry ? items[i].webkitGetAsEntry() : null;
                        if (item) {
                            pending++;
                            traverseFileTree(item, file => {
                                if (file && file.name.endsWith('.json')) {
                                    allFiles.push(file);
                            }
                            }, () => {
                                pending--;
                                if (pending === 0) {
                                    if (allFiles.length > 0) {
                                        uploadMultipleFiles(allFiles);
                                    } else {
                                        uploadStatus.innerHTML = '<div class="alert alert-danger">未检测到 JSON 文件</div>';
                                    }
                                }
                            });
                        } else if (dt.files && dt.files.length > 0) {
                            // 普通文件拖拽
                            files = Array.from(dt.files).filter(f => f.name.endsWith('.json'));
                            if (files.length > 0) {
                                // 修复：确保单文件拖拽也能正常上传
                                if (files.length === 1) {
                                    uploadFile(files[0]);
                                } else {
                                    uploadMultipleFiles(files);
                                }
                            }
                        }
                    }
                } else if (dt.files && dt.files.length > 0) {
                    // 兼容不支持 items 的浏览器
                    files = Array.from(dt.files).filter(f => f.name.endsWith('.json'));
                    if (files.length > 0) {
                        if (files.length === 1) {
                            uploadFile(files[0]);
                        } else {
                            uploadMultipleFiles(files);
                        }
                    }
                }
            }
            
            // 遍历文件树的辅助函数
            function traverseFileTree(item, callback, completed) {
                if (item.isFile) {
                    item.file(file => {
                        callback(file);
                        if (completed) completed();
                    });
                } else if (item.isDirectory) {
                    const dirReader = item.createReader();
                    dirReader.readEntries(entries => {
                        let pending = entries.length;
                        if (pending === 0) {
                            if (completed) completed();
                            return;
                        }
                        entries.forEach(entry => {
                            traverseFileTree(entry, callback, () => {
                                pending--;
                                if (pending === 0 && completed) completed();
                            });
                        });
                    });
                }
            }
        }

        // 上传多个文件
        function uploadMultipleFiles(files) {
            const uploadStatus = document.getElementById('upload-status');
            uploadStatus.innerHTML = '<div class="alert alert-info">正在上传 ' + files.length + ' 个文件...</div>';

            const formData = new FormData();
            files.forEach(file => {
                formData.append('file', file);
            });

            fetch('/api/upload', {
                method: 'POST',
                body: formData
            })
            .then(response => {
                if (response.ok) {
                    return response.json();
                } else {
                    throw new Error('上传失败');
                }
            })
            .then(data => {
                const successCount = data.saved ? data.saved.length : 0;
                const errorCount = data.errors ? data.errors.length : 0;
                
                if (errorCount > 0) {
                    uploadStatus.innerHTML = `<div class="alert alert-warning">成功上传 ${successCount} 个文件，${errorCount} 个文件上传失败</div>`;
                } else {
                    uploadStatus.innerHTML = `<div class="alert alert-success">成功上传 ${successCount} 个文件</div>`;
                }
                
                document.getElementById('file-input').value = '';
                document.getElementById('dir-input').value = '';
                loadFiles();
                setTimeout(() => {
                    uploadStatus.innerHTML = '';
                }, 3000);
            })
            .catch(error => {
                console.error('Upload error:', error);
                uploadStatus.innerHTML = '<div class="alert alert-danger">文件上传失败</div>';
            });
        }

        // 上传文件
        function uploadFile(file) {
            const uploadStatus = document.getElementById('upload-status');
            
            // 检查文件类型
            if (!file.name.endsWith('.json')) {
                uploadStatus.innerHTML = '<div class="alert alert-danger">请选择JSON格式的文件</div>';
                return;
            }
            
            uploadStatus.innerHTML = '<div class="alert alert-info">正在上传...</div>';

            const formData = new FormData();
            formData.append('file', file);

            fetch('/api/upload', {
                method: 'POST',
                body: formData
            })
            .then(response => {
                if (response.ok) {
                    return response.json();
                } else {
                    throw new Error('上传失败');
                }
            })
            .then(data => {
                uploadStatus.innerHTML = `<div class="alert alert-success">成功上传 ${data.saved.length} 个文件</div>`;
                document.getElementById('file-input').value = '';
                document.getElementById('dir-input').value = '';
                loadFiles();
                setTimeout(() => {
                    uploadStatus.innerHTML = '';
                }, 3000);
            })
            .catch(error => {
                console.error('Upload error:', error);
                uploadStatus.innerHTML = '<div class="alert alert-danger">文件上传失败</div>';
            });
        }
        
        // 一键删除文件
        function deleteAllFiles(type) {
            fetch('/api/files')
                .then(response => response.json())
                .then(data => {
                    const files = type === 'data' ? data.data_files : data.output_files;
                    if (files.length === 0) {
                        showFloatingToast('没有文件需要删除', 'info');
                        return;
                    }
                    
                    // 设置确认信息
                    document.getElementById('delete-filename').textContent = `所有${type === 'data' ? '输入' : '输出'}文件（共${files.length}个）`;
                    document.getElementById('confirm-delete-btn').onclick = function() {
                        performDeleteAll(type, files.map(f => f.name));
                        bootstrap.Modal.getInstance(document.getElementById('deleteConfirmModal')).hide();
                    };
                    
                    // 显示确认模态框
                    new bootstrap.Modal(document.getElementById('deleteConfirmModal')).show();
                })
                .catch(error => {
                    console.error('Error getting files:', error);
                    showFloatingToast('获取文件列表失败', 'danger');
                });
        }
        
        // 执行实际的一键删除操作
        function performDeleteAll(type, filenames) {
            if (filenames.length === 0) return;
            
            let successCount = 0;
            let failCount = 0;
            
            // 依次删除所有文件
            Promise.all(
                filenames.map(filename => 
                    fetch(`/api/delete/${type}/${filename}`, {
                        method: 'DELETE'
                    })
                    .then(response => {
                        if (response.ok) {
                            successCount++;
                        } else {
                            failCount++;
                        }
                    })
                    .catch(error => {
                        console.error(`Error deleting file ${filename}:`, error);
                        failCount++;
                    })
                )
            ).then(() => {
                loadFiles();
                if (failCount === 0) {
                    showFloatingToast(`成功删除${successCount}个文件`, 'success');
                } else {
                    showFloatingToast(`删除完成：成功${successCount}个，失败${failCount}个`, 'warning');
                }
            });
        }
    </script>
</body>
</html>